#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2006, Achraf Cherti.
#  
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
# 
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
# 
# You should have received a copy of the GNU General Public License
# along with This program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
#
"""Convert a Debian package to an Arch Linux package.

"""

# global imports
import sys
import os
from shutil import rmtree
from tempfile import mkdtemp

# local imports
import args
import misc

# global variables
VERSION = '0.1'

def read_debcontrol(path):
    """Read some informations since debian/control.

    """
    result = {'name':'', 'maintainer':'', 'version':'', 
              'description':'', 'size':'', 'architecture':''}

    try:
        filedesc = open(path, 'r')
    except IOError:
        print 'Cannot read debian package informations from \'%s\'.' % path
        sys.exit(1)

    for line in filedesc.readlines():
        line = line.rstrip('\n')
        try:
            (variable, value) = [splited.strip().lower() \
                                 for splited in line.split(':')]
        except ValueError:
            continue

        if variable == 'package':
            result['name'] = value
        if variable == 'installed-size':
            result['size'] = value
        elif variable in ['maintainer', 'version', \
                          'architecture', 'description']:
            result[variable] = value

    filedesc.close()

    for key, value in result.items():
        if value == '' and key not in ['size']:
            print 'The debian package doesn\'t ' \
                  'contain all needed informations.\n' \
                  'The variable \'%s\' is empty.' % key
            sys.exit(1)

    return result

def write_archcontrol(path, pkginfo):
    """Write an Arch Linux PKGINFO in 'path'.

    'pkginfo' is a dictionary which contain some informations
    returned by read_debcontrol().

    """
    try:
        filedesc = open(path, 'w')
    except IOError:
        print '\'%s\' is not accessible in writing.' % path
        sys.exit(1)

    filedesc.write('# Generated by Alien Arch version %s\n' % VERSION)
    filedesc.write('pkgname = %s\n' % pkginfo['name'])
    filedesc.write('pkgver = %s\n' % pkginfo['version'])
    filedesc.write('pkgdesc = %s\n' % pkginfo['description'])
    filedesc.write('packager = Arch Linux, Alien Arch ' \
                   '(http://www.archlinux.org)\n')
    filedesc.write('size = %s\n' % pkginfo['size'])
    filedesc.write('arch = %s\n' % pkginfo['architecture'])
    filedesc.write('license =\n')
    #filedesc.write('url =\n')
    #filedesc.write('builddate =\n')
    #filedesc.write('depend =\n')

    filedesc.close()

def convert(input_pkg, output_pkg=''):
    """Convert the input package (Debian format) to
    the output package (an Arch Linux package).

    input_pkg must contain the input package, with
    *.deb extension.

    output_pkg will contain the output package, with
    *.pkg.tar.gz extension. This argument is not 
    obligatory.

    NOTE: Be careful, this function uses os.chdir 
          to change the current directory.

    """
    (input_tmpd, output_tmpd) = (mkdtemp(), mkdtemp())

    input_pkg = misc.fix_input_pkg(input_pkg)
    print 'Conversion of %s...' % os.path.basename(input_pkg)
    print

    def chdir(directory):
        """Change directory"""
        try:
            os.chdir(directory)
        except OSError:
            print 'Cannot go into %s.' % directory
            sys.exit(1)

    try:
        chdir(input_tmpd)

        # Extraction of the deb archive
        os.system('ar x \'%s\'' % input_pkg)

        # Extraction of control.tar.gz and data.tar.gz
        os.system('tar xf \'%s\' -C \'%s\'' % \
                  (os.path.join(input_tmpd, 'data.tar.gz'), 
                   output_tmpd))
        os.system('tar xf \'%s\'' % \
                  (os.path.join(input_tmpd, 'control.tar.gz')))

        # Reading 'control' file, from the deb archive
        deb_info = read_debcontrol(os.path.join(input_tmpd, 'control'))

        # If the output filename is not specified, it will be created
        if output_pkg == '':
            output_pkg = os.path.join(os.path.dirname(input_pkg), 
                                      '%(name)s-%(version)s''.pkg.tar.gz' \
                                       % deb_info)
        
        # Creating Arch Linux package
        chdir(output_tmpd)
        os.system('find . -type f | sed -e \'s/^\\.\\///\' > .FILELIST')
        write_archcontrol('.PKGINFO', deb_info)
        os.system('tar zcf \'%s\' * .PKGINFO .FILELIST' % output_pkg)

        print "done."
        print
        print 'The Arch Linux package is in :\n%s' % output_pkg
    finally:
        rmtree(input_tmpd, True)
        rmtree(output_tmpd, True)

if __name__ == '__main__':
    try:
        misc.command_required('ar', 'tar', 'find', 'sed')
        DATA = args.handle_arguments()
        convert(DATA['input_pkg'],
                DATA['output_pkg'])
        # Supporter les scripts debian
    except KeyboardInterrupt:
        print "Interrupted."

# vim:ai:et:sw=4:ts=4:sts=4:tw=78:fenc=utf-8
